use Test::More tests => 38;

use strict;
use Zim;
use Zim::Repository::Files;
use File::Spec;

$| = 1;
$Zim::CODESET = 'utf8';
$SIG{__WARN__} = sub {
	print STDERR @_ unless $_[0] =~ /^(#|Searching|Indexing)/;
};

eval 'require Zim::Win32' if $^O eq 'MSWin32';
die $@ if $@;

my @clean = qw#
	.zim.cache
	Test/bar.txt
	new copy move Move
#;

# Clean
for (@clean) {
	my $f = Zim::File->new('t', 'repository', split '/', $_);
	$f->remove if $f->exists;
}


# Test a bunch of stuff in the "Files" backend

my $root = File::Spec->rel2abs( File::Spec->catdir(qw/t repository/) );
my $rep = Zim::Repository::Files->new(dir => $root);

is($rep->{format}, 'wiki', 'format'); # 1

print "\n## 2 file(foo:bar) resulted in: ".$rep->file('foo:bar')->path."\n";
ok($rep->file('foo:bar')->path =~ m#/t/repository/foo/bar.txt$#,
	'filename 1' ); # 2

my $page = $rep->get_page(':foo:bar');
is($page->status, 'new', 'status new page'); # 3
ok(@{$page->get_parse_tree} > 2, 'template'); # 4 
is($page->{format}, 'Zim::Formats::Wiki', 'format class'); # 5

ok($rep->file('Test:wiki')->path =~ m#/t/repository/Test/wiki.txt$#,
	'filename 2' ); # 6

print "\n## 7 - resolve_name test:WIKI => :Test:wiki\n";
my $name = $rep->resolve_name('test:WIKI');
is($name, ':Test:wiki', 'resolve_name'); # 7

$page = $rep->get_page(':Test:foo:bar');
print "\n## 8 - resolve_name Dus => :Test:foo:Dus\n";
$name = $page->resolve_name('Dus');
is($name, ':Test:foo:Dus', 'resolve_name 1'); # 8

$page = $rep->get_page(':Test:foo:bar');
print "\n## 9 - resolve_name wIKi => :Test:wiki\n";
$name = $page->resolve_name('wIKi');
is($name, ':Test:wiki', 'resolve_name 2'); # 9

$page = $rep->get_page(':Test:foo:bar');
print "\n## 10 - resolve_name Test:Dus => :Test:Dus\n";
$name = $page->resolve_name('Test:Dus');
is($name, ':Test:Dus', 'resolve_name 3'); # 10

$page = $rep->get_page(':Test:foo:bar');
print "\n## 11 - resolve_name test:Dus => :Test:Dus\n";
$name = $page->resolve_name('test:Dus');
is($name, ':Test:Dus', 'resolve_name 4'); # 11

$page = $rep->get_page(':Test:foo:bar');
print "\n## 12 - resolve_name test:WIKI:bar => :Test:wiki:bar\n";
$name = $page->resolve_name('test:WIKI:bar');
is($name, ':Test:wiki:bar', 'resolve_name 5'); # 12

$page = $rep->get_page(':Test:foo:bar');
print "\n## 13 - resolve_name :Dus => :Dus\n";
$name = $page->resolve_name(':Dus');
is($name, ':Dus', 'resolve_name 6'); # 13

$page = $rep->get_page(':Test:foo');
print "\n## 14 - resolve_name .bar => Test:foo:bar\n";
my (undef, $l) = $page->parse_link('.bar');
$name = $page->resolve_name($l);
is($name, ':Test:foo:bar', 'resolve_name 7'); # 14

#$page = $rep->open_page('test:utf8-acchars');

# Clean again
for (@clean) {
	my $f = Zim::File->new('t', 'repository', split '/', $_);
	$f->remove if $f->exists;
}

my @pages = $rep->list_pages(':');
#warn "Pages: ", map(">>$_<< ", @pages), "\n";
is_deeply(\@pages, [qw/Test:/], 'list_pages 1'); # 15

@pages = sort $rep->list_pages(':Test:');
#warn "Pages: ", map(">>$_<< ", @pages), "\n";
is_deeply(\@pages, [qw/foo: wiki/], 'list_pages 2'); # 16

# repeating previous test to catch bad caching
@pages = sort $rep->list_pages(':Test:');
#warn "Pages: ", map(">>$_<< ", @pages), "\n";
is_deeply(\@pages, [qw/foo: wiki/], 'list_pages 3'); # 17

# test caching in combo with new content
print "# sleeping 3 seconds ...\n";
print "# The following test may fail depending on IO buffering\n";
sleep 3; # make sure mtime is changed
Zim::File->new(qw/t repository Test bar.txt/)->write("=== Bar ===\n\nfoo bar !\n" );
@pages = sort $rep->list_pages(':Test:');
#warn "Pages: ", map(">>$_<< ", @pages), "\n";
is_deeply(\@pages, [qw/bar foo: wiki/], 'list_pages 4'); # 18

# create / move / copy / delete
$page = $rep->get_page(':new');
ok($page->status eq 'new', 'new page'); # 19

$page->set_parse_tree(['Page', {}, 'test 1 2 3']);
$page = $rep->get_page(':new');
ok($page->exists, 'create page'); # 20

$page->move( $rep->get_page(':move') ); # no root wrapper, so need object
$page = $rep->get_page(':new');
ok(! $page->exists, 'page move 1'); # 21
$page = $rep->get_page(':move');
ok($page->get_parse_tree()->[2][2] eq 'test 1 2 3', 'page move 2'); # 22
	# Returns like ['Page', {}, ['Para', {}, 'test 1 2 3']]

$page->copy( $rep->get_page(':copy') ); # no root wrapper, so need object
$page = $rep->get_page(':move');
ok($page->get_parse_tree()->[2][2] eq 'test 1 2 3', 'page copy 1');  #23 
$page = $rep->get_page(':copy');
ok($page->get_parse_tree()->[2][2] eq 'test 1 2 3', 'page copy 2'); # 24 

$rep->get_page(':move')->move( $rep->get_page(':Move') );
ok($rep->resolve_name('move') eq ':Move', 'move is case sensitive'); # 25

$rep->get_page(':Move')->delete;
$rep->get_page(':copy')->delete;
$page = $rep->get_page(':Move');
ok(!$page->exists, 'delete page 1'); # 26
$page = $rep->get_page(':copy');
ok(!$page->exists, 'delete page 2'); # 27

# Test dispatching to child rep
$rep = Zim->new(dir => $root);

$page = $rep->get_page(':test:wiki');
is($page->{repository}{namespace}, ':', 'Child repository dispatch 1'); # 28

$page = $rep->get_page(':foo:bar');
is($page->{repository}{namespace}, ':', 'Child repository dispatch 2'); # 29

# add child rep
my $node = File::Spec->catdir($root, 'Foo');
$rep->add_child(':foo', 'Files', dir => $node);

$page = $rep->get_page(':test:wiki');
is($page->{repository}{namespace}, ':', 'Child repository dispatch 3'); # 30

$page = $rep->get_page(':foo:bar');
is($page->{repository}{namespace}, ':foo:', 'Child repository dispatch 4'); # 31

$page = $rep->get_page(':Foo');
is($page->{repository}{namespace}, ':foo:', 'Child repository dispatch 5'); # 32

$page = $rep->get_page(':fooBar');
is($page->{repository}{namespace}, ':', 'Child repository dispatch 6'); # 33

ok(! -e $node, 'No pre-mature creation of repository dir'); # 34

# search
my @res;
my $cb = sub { push @res, @_ };
$rep->search({string => "\x{2022}\x{2022} Search Me \x{2022}\x{2022}"}, $cb);
#use Data::Dumper; print Dumper \@res;
ok(scalar( grep {$$_[0] eq ':Test:foo:bar' and $$_[1] > 0} @res),
	"utf8 search pattern" ); # 34

# Relative path
$page = $rep->resolve_page(':test:wiki');
my $path = File::Spec->catfile($root, 'foo.pdf');
ok($page->relative_path($path) eq '../foo.pdf', 'relative_path 1'); # 36
$path = File::Spec->catfile($root, 'Test', 'foo.pdf');
warn "### ", $page->relative_path($path), "\n";
ok($page->relative_path($path) eq './foo.pdf', 'relative_path 2'); # 37
$path = Zim::File->abs_path(
	File::Spec->catfile($root, '..', '..', 'foo.pdf') );
ok($page->relative_path($path) eq $path, 'relative_path 3'); # 38

